#include "string.h"
#include "usart.h"

#ifndef NULL
#define NULL			((void *)0)
#endif

static int pow10(int i)
{
	int sum = 1;
	while(i--)
	{
		sum *= 10;
	}
	return sum;
}

static int str_int_count(unsigned char *str)
{
	int i = 0, n = 0;
	if(NULL != str)
	{
		for(i = 0; 0 != str[i]; i++)
		{
			if('0' <= str[i] && '9' >= str[i])
			{
				n++;
			}
			else
			{
				break;
			}
		}
	}
	return n;
}

static int str_chr_count(unsigned char *str, char ch)
{
	int i = 0, n = 0;
	if(NULL != str)
	{
		for(i = 0; 0 != str[i] && 1024 > i; i++)
		{
			if(ch == str[i])
			{
				n++;
			}
		}
	}
	return n;
}

static int str_to_buf(unsigned char *str, unsigned char *buf, int size, int n)
{
	int i = 0;
	for(i = 0; size > i && n > i; i++)
	{
		buf[i] = str[i];
	}
	return i;
}

int str_len(unsigned char *str)
{
	int i = 0;
	if(NULL != str)
	{
		while(1)
		{
			if(0 != str[i])
			{
				i++;
			}
			else
			{
				return i;
			}
		}
	}
	return 0;
}

unsigned char *str_chr(unsigned char *str, char ch)
{
	int i = 0;
	if(NULL != str)
	{
		for(i = 0; 0 != str[i] && 1024 > i; i++)
		{
			if(ch == str[i])
			{
				return &str[i];
			}
		}
	}
	return NULL;
}

unsigned int str_to_ip(unsigned char *str)
{
	unsigned int n = 0;
	unsigned char ip[4] = {0, 0, 0, 0};

	unsigned char *token = NULL;

	if(NULL != str)
	{
		n = str_chr_count(str, '.');
		if(3 == n)
		{
			while(1)
			{
				token = str_chr(str, '.');
				if(0 < n)
				{
					if(NULL == token)
					{
						break;
					}
					else
					{
						ip[3 - n] = (unsigned char)atoi_r(str, token - str);
						str = token + 1;
						n--;
					}
				}
				else
				{
					ip[3] = (unsigned char)atoi_r(str, str_len(str));
					return (((unsigned int)ip[0]) << 24) | (((unsigned int)ip[1]) << 16) | (((unsigned int)ip[2]) << 8) | ((unsigned int)ip[3]);
				}
			}
		}
	}
	return 0;
}

void str_array_flip(unsigned char *array, int n)
{
	int i = 0;
	for(n -= 1; n - i >= 1; n--, i++)
	{
		array[i] = array[i] ^ array[n];
		array[n] = array[i] ^ array[n];
		array[i] = array[i] ^ array[n];
	}
}

unsigned char *itoa_r(int value, int mode, unsigned char *array, int array_num)
{
	int i = 0x0;
	unsigned int val = 0x0;

	if(0x0 == value)
	{
		array[0] = '0';
		if(1 == mode)
		{
			array[1] = 'x';
			array[2] = '0';
		}
	}
	else
	{
		val = (0 == mode && 0x0 > value ) ? (0x0 - value) : value;
		for(i = array_num - 0x2; val > 0x0 && i >= 0; i--, val /= (0 == mode) ? 0xA : 0x10)
		{
			array[i] = (0 == mode) ? ((val % 0xA) + '0') : (val % 0x10);
			if(0 != mode)
			{
				array[i] = 0x9 < array[i] ? array[i] - 0xA  + 'A': array[i] + '0';
			}
		}

		if(0 > value && 0 == mode)
		{
			array[i] = '-';
		}
		else if(1 == mode)
		{
			array[i--] = 'x';
			array[i] = '0';
		}
		else
		{
			i++;
		}
	}
	return array + i;
}

unsigned int atoi_r(unsigned char *str, int n)
{
	int i = 0;
	unsigned int sum = 0;
	unsigned char buf[32] = {0};

	str_to_buf(str, buf, sizeof(buf), n);
	if(n == str_int_count(buf))
	{
		for(i = n - 1; 0 <= i; i--)
		{
			buf[i] = str[n - 1 - i] - '0';
		}

		for(i = 0; n > i; i++)
		{
			sum += buf[i] * pow10(i);
		}
	}
	return sum;
}

void mem_set(unsigned char *buf, char ch, int size)
{
	int i = 0;
	for(i = 0; size > i; i++)
	{
		buf[i] = ch;
	}
}

void mem_zero(unsigned char *buf, int size)
{
	mem_set(buf, 0, size);
}

int mem_ncmp(unsigned char *src, unsigned char *dest, int size)
{
	int i = 0;
	for(i = 0; size > i; i++)
	{
		if(src[i] != dest[i])
		{
			return -1;
		}
	}
	return 0;
}

int endian_big_to_little(unsigned char *data, int len)
{
	switch(len)
	{
		case 1:
			return data[0];
		case 2:
			return data[0] << 8 | data[1];
		case 4:
			return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
		default:
			return 0;
	}
}